```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ArrayList扩容机制深度解析</title>
    <link href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <link href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <style>
        body {
            font-family: 'Noto Sans SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
            color: #333;
            line-height: 1.6;
        }
        .hero {
            background: linear-gradient(135deg, #6e8efb 0%, #a777e3 100%);
        }
        .code-block {
            background-color: #282c34;
            border-radius: 8px;
            padding: 1.5rem;
            position: relative;
        }
        .code-block::before {
            content: '';
            position: absolute;
            top: 12px;
            left: 12px;
            width: 12px;
            height: 12px;
            border-radius: 50%;
            background: #ff5f56;
            box-shadow: 20px 0 0 #ffbd2e, 40px 0 0 #27c93f;
        }
        .highlight {
            background: linear-gradient(90deg, rgba(135, 16, 148, 0.1) 0%, rgba(135, 16, 148, 0) 100%);
            padding: 0.2rem 0.4rem;
            border-radius: 4px;
        }
        .card:hover {
            transform: translateY(-5px);
            box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
        }
        .timeline-item::before {
            content: '';
            position: absolute;
            left: -1.5rem;
            top: 0;
            width: 12px;
            height: 12px;
            border-radius: 50%;
            background: #6e8efb;
        }
    </style>
</head>
<body class="bg-gray-50">
    <!-- Hero Section -->
    <section class="hero text-white py-20 px-4 md:py-32">
        <div class="container mx-auto max-w-5xl">
            <div class="flex flex-col items-center text-center">
                <h1 class="text-4xl md:text-6xl font-bold mb-6 font-serif">ArrayList扩容机制</h1>
                <p class="text-xl md:text-2xl max-w-3xl mb-8 opacity-90">深入解析Java集合框架中动态数组的扩容策略与实现细节</p>
                <div class="flex space-x-4">
                    <span class="px-4 py-2 bg-white bg-opacity-20 rounded-full">#Java</span>
                    <span class="px-4 py-2 bg-white bg-opacity-20 rounded-full">#数据结构</span>
                    <span class="px-4 py-2 bg-white bg-opacity-20 rounded-full">#性能优化</span>
                </div>
            </div>
        </div>
    </section>

    <!-- Main Content -->
    <main class="container mx-auto max-w-5xl px-4 py-12">
        <!-- Introduction -->
        <section class="mb-16">
            <div class="prose max-w-none">
                <p class="text-lg text-gray-700 leading-relaxed">
                    <span class="text-4xl float-left mr-3 -mt-1 font-serif font-bold text-purple-600">A</span>
                    <span class="font-bold">rrayList</span> 是Java集合框架中最常用的动态数组实现，其扩容机制通过将容量扩大为原容量的1.5倍来减少扩容频率。扩容时创建一个新的更大的数组，并将现有元素复制到新数组中。虽然扩容操作的性能开销是O(n)，但其策略旨在平衡内存使用和性能。扩容的设计使得ArrayList能够动态调整容量以适应不同的存储需求。
                </p>
            </div>
        </section>

        <!-- Trigger Conditions -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-8 font-serif flex items-center">
                <i class="fas fa-bolt text-yellow-500 mr-3"></i>
                <span>扩容触发条件</span>
            </h2>
            <div class="grid md:grid-cols-2 gap-8">
                <div class="bg-white p-6 rounded-xl shadow-md border-l-4 border-blue-500 card transition duration-300">
                    <h3 class="text-xl font-bold mb-3 flex items-center">
                        <i class="fas fa-plus-circle text-blue-500 mr-2"></i>
                        元素添加
                    </h3>
                    <p class="text-gray-700">当ArrayList的元素数量达到当前数组的容量时，尝试添加新元素将触发扩容。</p>
                </div>
                <div class="bg-white p-6 rounded-xl shadow-md border-l-4 border-purple-500 card transition duration-300">
                    <h3 class="text-xl font-bold mb-3 flex items-center">
                        <i class="fas fa-exclamation-triangle text-purple-500 mr-2"></i>
                        容量不足
                    </h3>
                    <p class="text-gray-700">如果在添加元素时发现当前容量不足，则需要扩容以容纳新元素。</p>
                </div>
            </div>
        </section>

        <!-- Expansion Process -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-8 font-serif flex items-center">
                <i class="fas fa-cogs text-gray-600 mr-3"></i>
                <span>扩容过程</span>
            </h2>
            
            <div class="mb-12">
                <h3 class="text-2xl font-bold mb-6 flex items-center">
                    <span class="w-8 h-8 bg-blue-500 text-white rounded-full flex items-center justify-center mr-3">1</span>
                    确定新容量
                </h3>
                <p class="text-gray-700 mb-6">
                    ArrayList扩容时，通常会将容量扩大为原容量的1.5倍（即50%增长）。这种增长策略有助于减少频繁的扩容操作，平衡了内存使用和性能开销。具体扩容策略如下：
                </p>
                <div class="code-block text-gray-200 mb-6 overflow-x-auto">
                    <pre><code class="language-java">private void ensureCapacity(int minCapacity) {
    // 获取当前数组的容量
    int oldCapacity = elementData.length;
    // 如果当前容量小于最小容量，则需要扩容
    if (minCapacity > oldCapacity) {
        // 新容量通常是当前容量的1.5倍
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        // 确保新容量至少满足最小容量要求
        if (newCapacity < minCapacity) {
            newCapacity = minCapacity;
        }
        // 扩容
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
}</code></pre>
                </div>
                <p class="text-gray-700">
                    <span class="highlight">1.5</span> 是通过位运算的右移操作计算的，即 <span class="highlight">oldCapacity >> 1</span> 是 <span class="highlight">oldCapacity / 2</span>，将其加到 <span class="highlight">oldCapacity</span> 上形成新容量。
                </p>
            </div>

            <div class="grid md:grid-cols-3 gap-8 mb-12">
                <div class="bg-white p-6 rounded-xl shadow-md card transition duration-300">
                    <h3 class="text-xl font-bold mb-3 flex items-center">
                        <i class="fas fa-file-code text-green-500 mr-2"></i>
                        创建新数组
                    </h3>
                    <p class="text-gray-700">在扩容时，ArrayList会创建一个新的、更大的数组，大小为原数组容量的1.5倍或满足最小容量的要求。</p>
                </div>
                <div class="bg-white p-6 rounded-xl shadow-md card transition duration-300">
                    <h3 class="text-xl font-bold mb-3 flex items-center">
                        <i class="fas fa-copy text-orange-500 mr-2"></i>
                        复制元素
                    </h3>
                    <p class="text-gray-700">ArrayList会将原数组中的所有元素复制到新的数组中。这个过程是通过Arrays.copyOf方法完成的，时间复杂度为O(n)。</p>
                </div>
                <div class="bg-white p-6 rounded-xl shadow-md card transition duration-300">
                    <h3 class="text-xl font-bold mb-3 flex items-center">
                        <i class="fas fa-sync-alt text-red-500 mr-2"></i>
                        更新引用
                    </h3>
                    <p class="text-gray-700">将原数组的引用更新为新数组的引用。这样，ArrayList就会使用新数组来存储后续的元素。</p>
                </div>
            </div>
        </section>

        <!-- Impact & Strategy -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-8 font-serif flex items-center">
                <i class="fas fa-chart-line text-green-500 mr-3"></i>
                <span>扩容的影响与策略</span>
            </h2>
            
            <div class="grid md:grid-cols-2 gap-8 mb-12">
                <div>
                    <h3 class="text-2xl font-bold mb-4">性能影响</h3>
                    <p class="text-gray-700 mb-6">
                        扩容是一个O(n)操作，因为需要将所有现有的元素从旧数组复制到新数组。虽然扩容会引起性能开销，但由于扩容的频率较低，这种开销通常是可以接受的。扩容后的ArrayList会有更多的空间，可以容纳更多的元素，从而减少了未来扩容的频率。
                    </p>
                    <div class="bg-blue-50 p-4 rounded-lg border border-blue-100">
                        <h4 class="font-bold text-blue-800 mb-2 flex items-center">
                            <i class="fas fa-lightbulb mr-2"></i>
                            优化建议
                        </h4>
                        <p class="text-blue-700">
                            如果事先知道大致需要存储的元素数量，可以在创建ArrayList时指定初始容量，避免多次扩容带来的性能损耗。
                        </p>
                    </div>
                </div>
                <div>
                    <h3 class="text-2xl font-bold mb-4">空间使用</h3>
                    <p class="text-gray-700 mb-6">
                        扩容会增加内存使用，因为新的数组需要额外的空间来存储元素。然而，扩容策略的设计旨在平衡内存使用和性能开销，通过增加一定比例的空间来降低扩容的频率。
                    </p>
                    <div class="flex items-center">
                        <div class="w-1/2 pr-4">
                            <div class="h-4 bg-gray-200 rounded-full overflow-hidden">
                                <div class="h-full bg-purple-500" style="width: 100%"></div>
                            </div>
                            <p class="text-sm text-center mt-1">初始容量</p>
                        </div>
                        <div class="w-1/2 pl-4">
                            <div class="h-4 bg-gray-200 rounded-full overflow-hidden">
                                <div class="h-full bg-purple-500" style="width: 150%"></div>
                            </div>
                            <p class="text-sm text-center mt-1">1.5倍扩容</p>
                        </div>
                    </div>
                </div>
            </div>

            <div class="bg-white p-6 rounded-xl shadow-md mb-8">
                <h3 class="text-2xl font-bold mb-4">初始容量与增长策略</h3>
                <ul class="space-y-4">
                    <li class="flex items-start">
                        <i class="fas fa-chevron-right text-purple-500 mt-1 mr-2"></i>
                        <div>
                            <span class="font-bold">初始容量：</span>ArrayList的初始容量是创建时指定的，默认情况下为10。如果在创建ArrayList时提供了初始容量，则扩容将在达到该容量时触发。
                        </div>
                    </li>
                    <li class="flex items-start">
                        <i class="fas fa-chevron-right text-purple-500 mt-1 mr-2"></i>
                        <div>
                            <span class="font-bold">增长策略：</span>默认的增长策略是将容量扩大为原容量的1.5倍。这种策略在许多情况下能有效减少扩容的频率，同时平衡了内存和性能需求。
                        </div>
                    </li>
                </ul>
            </div>
        </section>

        <!-- Implementation Details -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-8 font-serif flex items-center">
                <i class="fas fa-code text-gray-600 mr-3"></i>
                <span>实现细节</span>
            </h2>
            
            <div class="grid md:grid-cols-2 gap-8">
                <div class="bg-white p-6 rounded-xl shadow-md">
                    <h3 class="text-xl font-bold mb-4 flex items-center">
                        <i class="fas fa-check-circle text-blue-500 mr-2"></i>
                        ensureCapacity()方法
                    </h3>
                    <p class="text-gray-700 mb-4">
                        ArrayList提供了ensureCapacity方法来确保容量足够容纳指定数量的元素。这个方法会检查当前容量，并在需要时进行扩容。扩容策略是通过计算新容量并创建新数组来实现的。
                    </p>
                    <div class="bg-gray-50 p-4 rounded-lg">
                        <p class="text-sm text-gray-600">
                            <span class="font-bold">使用场景：</span>当你知道将要添加大量元素时，可以提前调用此方法以避免多次扩容。
                        </p>
                    </div>
                </div>
                <div class="bg-white p-6 rounded-xl shadow-md">
                    <h3 class="text-xl font-bold mb-4 flex items-center">
                        <i class="fas fa-copy text-green-500 mr-2"></i>
                        Arrays.copyOf()
                    </h3>
                    <p class="text-gray-700 mb-4">
                        Arrays.copyOf是扩容过程中用来复制数组的工具方法，能够高效地将旧数组中的元素复制到新数组中。
                    </p>
                    <div class="bg-gray-50 p-4 rounded-lg">
                        <p class="text-sm text-gray-600">
                            <span class="font-bold">性能：</span>这是一个本地方法(native method)，在底层使用系统级的内存拷贝操作，效率较高。
                        </p>
                    </div>
                </div>
            </div>
        </section>

        <!-- Source Code Analysis -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-8 font-serif flex items-center">
                <i class="fas fa-microscope text-red-500 mr-3"></i>
                <span>源码分析</span>
            </h2>
            
            <div class="bg-white rounded-xl shadow-md overflow-hidden mb-8">
                <img src="https://cdn.nlark.com/yuque/0/2021/png/21449790/1634001205806-18284b0b-ddee-48b3-8535-17fc5892c19b.png" alt="ArrayList底层实现" class="w-full">
                <div class="p-6">
                    <p class="text-gray-700">
                        ArrayList底层通过一个数组来实现，也就是说放在ArrayList中的数据其实是放在数组中的(<span class="highlight">elementData</span>)。那这个数组的长度是多少呢？
                    </p>
                </div>
            </div>

            <div class="grid md:grid-cols-2 gap-8 mb-8">
                <div>
                    <h3 class="text-xl font-bold mb-4 flex items-center">
                        <i class="fas fa-code-branch text-blue-500 mr-2"></i>
                        指定初始长度
                    </h3>
                    <div class="bg-white rounded-xl shadow-md overflow-hidden">
                        <img src="https://cdn.nlark.com/yuque/0/2021/png/21449790/1634001785204-09717433-17f7-4956-85bb-cca677132866.png" alt="指定初始长度的构造器" class="w-full">
                        <div class="p-4">
                            <p class="text-gray-700 text-sm">
                                如果在构造器中设置了长度，那数组的长度就是指定的。
                            </p>
                        </div>
                    </div>
                </div>
                <div>
                    <h3 class="text-xl font-bold mb-4 flex items-center">
                        <i class="fas fa-code-branch text-purple-500 mr-2"></i>
                        默认构造器
                    </h3>
                    <div class="bg-white rounded-xl shadow-md overflow-hidden">
                        <img src="https://cdn.nlark.com/yuque/0/2021/png/21449790/1634001843660-6da8519b-359d-48f9-87a1-f03407acf29a.png" alt="默认构造器" class="w-full">
                        <div class="p-4">
                            <p class="text-gray-700 text-sm">
                                在构造器中只做了一件时间就是给elementData做初始化操作，长度是0。
                            </p>
                        </div>
                    </div>
                </div>
            </div>

            <div class="bg-white p-6 rounded-xl shadow-md mb-8">
                <h3 class="text-xl font-bold mb-4 flex items-center">
                    <i class="fas fa-plus-circle text-green-500 mr-2"></i>
                    add方法中的扩容
                </h3>
                <div class="grid md:grid-cols-2 gap-6">
                    <div>
                        <img src="https://cdn.nlark.com/yuque/0/2021/png/21449790/1634001901961-9f8fe3b1-f4aa-461c-8d62-5c556b1cfb9c.png" alt="add方法" class="w-full rounded-lg shadow-sm mb-3">
                        <p class="text-gray-700 text-sm">
                            在add方法里面完成了数组的扩容，默认长度是10。
                        </p>
                    </div>
                    <div>
                        <img src="https://cdn.nlark.com/yuque/0/2021/png/21449790/1634002050341-3fceeab4-a494-498f-9dab-8f3277fa0e51.png" alt="扩容细节" class="w-full rounded-lg shadow-sm">
                    </div>
                </div>
                <div class="mt-6 bg-yellow-50 p-4 rounded-lg border border-yellow-200">
                    <p class="text-yellow-800">
                        <span class="font-bold">关键发现：</span>第二次扩容的时候新数组的长度是旧数组的1.5倍。
                    </p>
                </div>
            </div>

            <div class="grid md:grid-cols-3 gap-6">
                <div class="bg-white p-4 rounded-xl shadow-sm">
                    <h4 class="font-bold mb-2 flex items-center">
                        <i class="fas fa-search text-blue-500 mr-2"></i>
                        get方法
                    </h4>
                    <img src="https://cdn.nlark.com/yuque/0/2022/png/21449790/1651039990828-9ce6fec3-9130-44e8-9ed6-8afbbe54cf9a.png" alt="get方法" class="w-full rounded-lg mb-2">
                    <img src="https://cdn.nlark.com/yuque/0/2022/png/21449790/1651039999438-e509376c-75c4-47ef-b1ac-e51a6ac3012c.png" alt="get方法细节" class="w-full rounded-lg">
                </div>
                <div class="bg-white p-4 rounded-xl shadow-sm">
                    <h4 class="font-bold mb-2 flex items-center">
                        <i class="fas fa-trash-alt text-red-500 mr-2"></i>
                        remove方法
                    </h4>
                    <img src="https://cdn.nlark.com/yuque/0/2022/png/21449790/1651040418580-2918b5ef-fd57-4c09-b6e8-0c4c91ecd0cc.png" alt="remove方法" class="w-full rounded-lg">
                </div>
                <div class="bg-white p-4 rounded-xl shadow-sm">
                    <h4 class="font-bold mb-2 flex items-center">
                        <i class="fas fa-broom text-gray-500 mr-2"></i>
                        clear方法
                    </h4>
                    <img src="https://cdn.nlark.com/yuque/0/2022/png/21449790/1651040472600-436338a8-23ce-4f47-9c6b-97d1b77a290c.png" alt="clear方法" class="w-full rounded-lg">
                </div>
            </div>
        </section>

        <!-- Summary Diagram -->
        <section class="mb-16">
            <h2 class="text-3xl font-bold mb-8 font-serif flex items-center">
                <i class="fas fa-project-diagram text-purple-500 mr-3"></i>
                <span>ArrayList扩容机制流程图</span>
            </h2>
            
            <div class="bg-white p-6 rounded-xl shadow-md">
                <div class="mermaid">
                    graph TD
                        A[添加元素] --> B{当前容量是否足够?}
                        B -->|是| C[添加元素到数组]
                        B -->|否| D[计算新容量: oldCapacity + (oldCapacity >> 1)]
                        D --> E{新容量是否足够?}
                        E -->|否| F[使用minCapacity作为新容量]
                        E -->|是| G[创建新数组]
                        F --> G
                        G --> H[复制元素到新数组]
                        H --> I[更新数组引用]
                        I --> C
                </div>
            </div>
        </section>
    </main>

    <!-- Footer -->
    <footer class="bg-gray-900 text-gray-300 py-12">
        <div class="container mx-auto max-w-5xl px-4">
            <div class="flex flex-col items-center">
                <h3 class="text-xl font-bold mb-2 text-white">技术小馆</h3>
                <a href="http://www.yuque.com/jtostring" class="text-blue-400 hover:text-blue-300 transition duration-200">
                    <i class="fas fa-external-link-alt mr-1"></i>
                    http://www.yuque.com/jtostring
                </a>
                <div class="mt-6 flex space-x-4">
                    <a href="#" class="w-8 h-8 rounded-full bg-gray-700 flex items-center justify-center hover:bg-blue-500 transition duration-200">
                        <i class="fab fa-github"></i>
                    </a>
                    <a href="#" class="w-8 h-8 rounded-full bg-gray-700 flex items-center justify-center hover:bg-blue-400 transition duration-200">
                        <i class="fab fa-twitter"></i>
                    </a>
                    <a href="#" class="w-8 h-8 rounded-full bg-gray-700 flex items-center justify-center hover:bg-red-500 transition duration-200">
                        <i class="fab fa-youtube"></i>
                    </a>
                </div>
            </div>
        </div>
    </footer>

    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <script>
        mermaid.initialize({
            startOnLoad: true,
            theme: 'default',
            flowchart: {
                useMaxWidth: true,
                htmlLabels: true,
                curve: 'basis'
            }
        });
        
        // 添加简单的滚动动画
        document.querySelectorAll('a[href^="#"]').forEach(anchor => {
            anchor.addEventListener('click', function (e) {
                e.preventDefault();
                document.querySelector(this.getAttribute('href')).scrollIntoView({
                    behavior: 'smooth'
                });
            });
        });
    </script>
</body>
</html>
```